import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.geom.AffineTransform;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

import org.iforce2d.Jb2dJson;
import org.jbox2d.common.Vec2;
import org.jbox2d.dynamics.World;

//import DatabaseManager.LevelWorld;

public class GameScreen extends JPanel implements ActionListener, KeyListener {
	private Image[] backgroundImage;
	private static GameScreen gameScreenInstance;
	private GameEngine gameEngine;
	Timer time;
	Graphics2D drawer;
	GameObject[][] levelData;
	World world;
	
	int a, b;
	//private LevelWorld levelWorld;

	private GameScreen() throws IOException {
		gameEngine = GameEngine.createGameEngine();
		backgroundImage = new Image[1];
		backgroundImage[0] = ImageIO.read(new File("assets/background1.png"));
		a = 43;
		b = 24;
		time = new Timer(1, this);
		setFocusable(true);
		this.addKeyListener(this);
		
	}
	

	public static GameScreen createGameScreen() throws IOException {
		if( gameScreenInstance == null )
		{
			return new GameScreen();
		}
		else
		{
			return gameScreenInstance;
		}
	}

	public void draw(GameObject[][] levelData, World world) throws IOException {
		//levelData[0][0].physicsProperties.setTransform(new Vec2(300,80), 0);
		
		this.levelData = levelData;
		this.world = world;
		repaint();
		/*for( GameObject[] i : levelData )
		{
			for( GameObject j : i )
			{
				j.draw( drawer );
			}
			
		}
		repaint();*/
		//update( g );
	}
	
	/*@Override
	public void repaint() {
		//mainWorld.step(60, 8, 3);
		super.repaint();

		//levelData[0][0].physicsProperties.setTransform(new Vec2(300,80), 0);
	};*/
	@Override
	public void paintComponent(Graphics g) {
      super.paintComponent(g);  // paint background
      setBackground(Color.BLACK);
      
      gameEngine.getWorld().drawDebugData();
      
      // Your custom painting codes
      // ......
      drawer = (Graphics2D)g;
      drawer.drawImage(backgroundImage[0], a, b, null);
      
      if( gameEngine.getLevelData() != null )
      {
	      for( GameObject[] i : gameEngine.getLevelData() )
		  {
		  	  for( GameObject j : i )
			  {
				  try {
					j.draw( g );
					//System.out.println("--------------draw gameobject");
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			  }
			
		  }
      }
      
      repaint();
   }
	
	@Override
	public void repaint() {
		super.repaint();
		if( gameEngine != null )
		{
			if( gameEngine.getWorld() != null )
			{
				gameEngine.getWorld().step(0.00025f, 0, 0);
				
				//b.setLinearVelocity(new Vec2(200, 100));
				//gameEngine.getLevelData()[0][0].physicsProperties.setLinearVelocity(new Vec2( 1500, -900 ));
				gameEngine.getLevelData()[0][1].physicsProperties.setLinearVelocity(new Vec2( 0, -100 ));
				//System.out.println("stepping the world " + gameEngine.getLevelData()[0][0].physicsProperties.getPosition().x + "\n y: " + gameEngine.getLevelData()[0][0].physicsProperties.getPosition().y + " \nmass: " + gameEngine.getLevelData()[0][0].physicsProperties.getMass() );
			}
		//a += 1;
		}
	};


	public void hide() {
		
	}

	public void show() {
		
	}

	public void drawHUD(int currentLevel, int currentScore, int bombsLeft, int enemiesLeft) {
		
	}


	@Override
	public void actionPerformed(ActionEvent arg0) {
		// TODO Auto-generated method stub
		a += 1;
		repaint();
	}


	@Override
	public void keyPressed(KeyEvent arg0) {
		System.out.println("Key Pressed");
		// TODO Auto-generated method stub
		if( arg0.getKeyCode() == KeyEvent.VK_S)
		{
			gameEngine.getLevelData()[0][0].physicsProperties.setLinearVelocity(new Vec2( gameEngine.getLevelData()[0][0].physicsProperties.getLinearVelocity().x, gameEngine.getLevelData()[0][0].physicsProperties.getLinearVelocity().y + 500 ));
			System.out.println("Key D Pressed");
		}
		if( arg0.getKeyCode() == KeyEvent.VK_W)
		{
			gameEngine.getLevelData()[0][0].physicsProperties.setLinearVelocity(new Vec2( gameEngine.getLevelData()[0][0].physicsProperties.getLinearVelocity().x, gameEngine.getLevelData()[0][0].physicsProperties.getLinearVelocity().y - 500 ));
			System.out.println("Key A Pressed");
		}
		if( arg0.getKeyCode() == KeyEvent.VK_D)
		{
			gameEngine.getLevelData()[0][0].physicsProperties.setLinearVelocity(new Vec2( gameEngine.getLevelData()[0][0].physicsProperties.getLinearVelocity().x + 500, gameEngine.getLevelData()[0][0].physicsProperties.getLinearVelocity().y ));
			System.out.println("Key W Pressed");
		}
		if( arg0.getKeyCode() == KeyEvent.VK_A)
		{
			gameEngine.getLevelData()[0][0].physicsProperties.setLinearVelocity(new Vec2( gameEngine.getLevelData()[0][0].physicsProperties.getLinearVelocity().x - 500, gameEngine.getLevelData()[0][0].physicsProperties.getLinearVelocity().y ));
			System.out.println("Key S Pressed");
		}
		
	}


	@Override
	public void keyReleased(KeyEvent arg0) {
		// TODO Auto-generated method stub
		
	}


	@Override
	public void keyTyped(KeyEvent arg0) {
		// TODO Auto-generated method stub
		
	}
}